#include <iostream>
#include "Mutex.hpp"
#include <unistd.h>
#include <string>
#include <vector>

using namespace std;

//共享资源:火车票

// pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;//锁de静态初始化
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int tickets = 1000;

//就需要尽可能的让多个线程交叉执行
//多个线程交叉执行本质：就是让调度器尽可能的频繁发生线程调度与切换
//线程一般在什么时候发生切换呢？时间片到了，来了更高优先级的线程，线程等待的时候。
//线程是在什么时候检测上面的问题呢？从内核态返回用户态的时候，线程要对调度状态进行检测，如果可以，就直接发生线程切换

class ThreadData
{
public:
    ThreadData(const string &name , pthread_mutex_t* p_mutex)
        :_name(name)
        ,_p_mutex(p_mutex)
    {}
    ~ThreadData(){}
public:
    string _name;
    pthread_mutex_t * _p_mutex;
};



void* getTicket(void*args)
{
    // string userName = static_cast<char*>(args);
    ThreadData* td = static_cast<ThreadData*>(args);
    LockGuard lockguard(&lock);
    while(true)
    {
        // pthread_mutex_lock(&lock);//加锁
        //加锁和解锁的过程多个线程串行执行的，程序变慢了！
        //锁只规定互斥访问，没有规定必须让谁优先执行
        //锁就是真是的让多个执行流进行竞争的结果
        // pthread_mutex_lock(&lock);
        // pthread_mutex_lock(&lock);
        if(tickets>0)
        {
            usleep(1000);
            cout<< td->_name << "正在抢票: " << tickets <<endl;
            tickets --;
            // pthread_mutex_unlock(&lock);//解锁
            // pthread_mutex_unlock(&lock);
        }
        else
        {
            // pthread_mutex_unlock(&lock);//解锁
            // pthread_mutex_unlock(&lock);
            break;
        }
        //抢完票就完了了吗？当然不是
        usleep(1000);//形成一个订单给用户
    }
    return nullptr;
}


int main()
{
#define NUM 4
    // pthread_mutex_t lock;
    // pthread_mutex_init(&lock,nullptr);//动态初始化
    vector<pthread_t> tids(NUM);

    for(int i = 0;i < NUM ;i++)
    {
        char buffer[1024];
        snprintf(buffer,sizeof(buffer),"thread %d", i+1 );
        ThreadData *td = new ThreadData(buffer,&lock);
        pthread_create(&tids[i],nullptr,getTicket,(void*)td);
    }

    for(const auto&tid : tids)
    {
        pthread_join(tid,nullptr);
    }


    return 0;
}